package com.ruoyi.function.service.impl;

import com.aliyun.cloudauth20190307.models.Id2MetaPeriodVerifyRequest;
import com.aliyun.cloudauth20190307.models.Id2MetaPeriodVerifyResponse;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.function.constant.BusinessConstants;
import com.ruoyi.function.domain.Garage;
import com.ruoyi.function.domain.Technician;
import com.ruoyi.function.domain.TransferResult;
import com.ruoyi.function.domain.bo.TechnicianSearchReqBo;
import com.ruoyi.function.domain.bo.UserBo;
import com.ruoyi.function.domain.vo.GarageVo;
import com.ruoyi.function.domain.vo.TechnicianVo;
import com.ruoyi.function.domain.vo.UserListVo;
import com.ruoyi.function.domain.vo.UserVo;
import com.ruoyi.function.mapper.GarageMapper;
import com.ruoyi.function.mapper.TechnicianMapper;
import com.ruoyi.function.mapper.TransferResultMapper;
import com.ruoyi.function.service.IUserService;
import com.ruoyi.function.utility.AliyunConfig;
import com.ruoyi.system.mapper.SysDictDataMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * 用户信息Service业务层处理
 *
 * @author ruoyi
 * @date 2025-03-18
 */
@Service
public class UserServiceImpl implements IUserService {
    private static final Logger log = LoggerFactory.getLogger(IUserService.class);
    @Autowired
    private SysUserMapper userMapper;
    @Autowired
    private AliyunConfig aliyunConfig;
    @Autowired
    private GarageMapper garageMapper;
    @Autowired
    private TechnicianMapper technicianMapper;
    @Autowired
    private SysDictDataMapper sysDictDataMapper;
    @Autowired
    private TransferResultMapper TransferResultMapper;


    @Override
    public boolean submitIdCardAuth(UserBo userBo) {
        // 获取当前用户id
        Long userId = SecurityUtils.getUserId();
        SysUser user1 = userMapper.selectUserById(userId);
        if (1 == user1.getRealNameAuthStatus()) {
            throw new ServiceException("用户已经实名认证");
        }
        userBo.setUserId(userId);
        log.info("提交身份证认证 - userId: {}, realName: {}, idCardNo: {}",
                userBo.getUserId(), userBo.getRealName(), userBo.getIdCardNo());

        // 1. 验证身份证有效期
        boolean verifyResult = verifyIdCardPeriod(userBo.getRealName(), userBo.getIdCardNo(),
                userBo.getValidityStartDate(), userBo.getValidityEndDate());
        if (!verifyResult) {
            throw new ServiceException("身份证有效期验证失败");
        }
        // 3. 更新用户实名认证信息
        userBo.setRealNameAuthStatus(1);
        SysUser user = new SysUser();
        BeanUtils.copyProperties(userBo, user);

        int i = userMapper.updateUser(user);
        return i > 0 ? true : false;
    }

    @Override
    public UserVo getMyinfo(Long userId) {
        // 从数据库中根据用户ID查询用户信息
        SysUser user = userMapper.selectUserById(userId);
        // 创建一个新的UserVo对象，用于存储转换后的用户信息
        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(user, userVo);
        // 获取并处理车库信息
        processGarageInfo(userId, userVo);
        // 获取并处理技术员信息
        processTechnicianInfo(userId, userVo);
        // 处理用户角色类型，将其转换为数组形式
        if (user.getRoleTypes() != null) {
            userVo.setUserTypesArray(user.getRoleTypes().split(","));
        }
        if (user.getModelId() != null) {
            userVo.setModelIdArray(user.getModelId().split(","));
        }


        userVo.setPassword("");
        // 返回包含完整用户信息的UserVo对象
        return userVo;
    }

    private List<TransferResult> selectTransferResultList(UserVo userVo) {
        TransferResult transferResult = new TransferResult();
        transferResult.setUserId(userVo.getUserId());
        transferResult.setState(BusinessConstants.WAIT_USER_CONFIRM);
        transferResult.setUserType(userVo.getUserType());
        return TransferResultMapper.selectTransferResultList(transferResult);
    }

    // 处理车库信息的私有方法
    private void processGarageInfo(Long userId, UserVo userVo) {
        // 根据用户ID从数据库中查询车库信息
        Garage garage = garageMapper.selectByUserId(userId);
        // 如果车库信息存在且审核状态为已通过
        String roleTypes = userVo.getRoleTypes();
        if (StringUtils.isNotNull(garage)) {
            GarageVo garageVo = mapGarageToGarageVo(garage);
            if (StringUtils.isNotNull((garage.getAppointmentTime()))){
                garageVo.setAppointmentTime(DateUtils.getMaxTime(garage.getCreateTime(), new Date()));
            }
            // 将转换后的车库信息设置到UserVo对象中
            userVo.setGarageVo(garageVo);
            List<TransferResult> transferResults = selectTransferResultList(userVo);
            garageVo.setTransferResults(transferResults);
        }
        //查询有没有到账的钱


    }

    // 处理技术员信息的私有方法
    private void processTechnicianInfo(Long userId, UserVo userVo) {
        // 根据用户ID从数据库中查询技术员信息
        Technician technician = technicianMapper.selectByUserId(userId);
        // 如果技术员信息存在且审核状态为已通过
        if (StringUtils.isNotNull(technician)){
            // 不存在的时候进入
            TechnicianVo technicianVo = mapTechnicianToTechnicianVo(technician);
            if (StringUtils.isNotNull(technicianVo.getAppointmentTime()) ){
                technicianVo.setAppointmentTime(DateUtils.getMaxTime(technicianVo.getCreateTime(), new Date()));
            }
            List<TransferResult> transferResults = selectTransferResultList(userVo);
            technicianVo.setTransferResults(transferResults);
            userVo.setTechnicianVo(technicianVo);
        }


    }

    // 将Garage对象转换为GarageVo对象的私有方法
    private GarageVo mapGarageToGarageVo(Garage garage) {
        // 创建一个新的GarageVo对象
        GarageVo garageVo = new GarageVo();
        // 将Garage对象的属性复制到GarageVo对象中
        BeanUtils.copyProperties(garage, garageVo);

        // 将服务区域、运输许可证、店铺照片和服务类型ID等字符串转换为数组
        garageVo.setServiceAreasList(splitString(garage.getServiceAreas()));
        garageVo.setTransportLicenses(splitString(garage.getTransportLicense()));
        garageVo.setShopPhotosList(splitString(garage.getShopPhotos()));
        garageVo.setServiceTypeIdsArray(splitString(garage.getServiceTypeIds()));

        // 返回转换后的GarageVo对象
        return garageVo;
    }

    // 将Technician对象转换为TechnicianVo对象的私有方法
    private TechnicianVo mapTechnicianToTechnicianVo(Technician technician) {
        // 创建一个新的TechnicianVo对象
        TechnicianVo technicianVo = new TechnicianVo();
        // 将Technician对象的属性复制到TechnicianVo对象中
        BeanUtils.copyProperties(technician, technicianVo);

        // 将经验照片、服务类型ID、服务区域、技能证书和平台证书等字符串转换为数组
        technicianVo.setExperiencePhotosList(splitString(technician.getExperiencePhotos()));
        technicianVo.setServiceTypeIdsArray(splitString(technician.getServiceTypeIds()));
        technicianVo.setServiceAreasList(splitString(technician.getServiceAreas()));
        technicianVo.setSkillCertificates(splitString(technician.getSkillCertificate()));
        technicianVo.setPlatformCertificates(splitString(technician.getPlatformCertificate()));
        // 返回转换后的TechnicianVo对象
        return technicianVo;
    }

    // 将逗号分隔的字符串转换为字符串数组的私有方法
    private String[] splitString(String input) {
        // 如果输入字符串不为空，则按逗号分割并返回数组，否则返回null
        return input != null ? input.split(",") : null;
    }

    // 查询用户和商户
    @Override
    public List<UserListVo> selectUserListVo(TechnicianSearchReqBo technicianSearchReqBo) {

        List<UserListVo> list1 = new ArrayList<>();
        if (StringUtils.isNotEmpty(technicianSearchReqBo.getServiceTypeName())) {
            String serviceTypeId = sysDictDataMapper.getDictValueByDictType("service_type", technicianSearchReqBo.getServiceTypeName());
            if (StringUtils.isEmpty(serviceTypeId)) {
                return list1;
            }
            technicianSearchReqBo.setServiceTypeIds(serviceTypeId);
        }

        technicianSearchReqBo.setAuditStatus(BusinessConstants.dict.audit_status_2);
        technicianSearchReqBo.setReceivingOrder(BusinessConstants.dict.receiving_order_1);
        if (BusinessConstants.dict.user_type_2 == technicianSearchReqBo.getUserType()) {
            // 查询用户类型是技术的
            List<Technician> list = technicianMapper.selectUserListVo(technicianSearchReqBo);

            for (Technician technician : list) {
                UserListVo userListVo = mapTechnicianToUserListVo(technician);
                list1.add(userListVo);
            }

        } else if (BusinessConstants.dict.user_type_3 == technicianSearchReqBo.getUserType()) {

            // 先默认给0，后面新增计算逻辑
            technicianSearchReqBo.setWorkstationsNumber(0);
            List<Garage> list = garageMapper.selectUserListVo(technicianSearchReqBo);
            for (Garage garage : list) {
                UserListVo userListVo = mapGarageToUserListVo(garage);
                list1.add(userListVo);
            }
        }
        return list1;
    }

    private UserListVo mapGarageToUserListVo(Garage garage) {
        UserListVo userListVo = new UserListVo();
        userListVo.setUserId(garage.getUserId());
        userListVo.setName(garage.getGarageName());
        userListVo.setAvatar(garage.getAvatar());
        userListVo.setPhone(garage.getContactMobile());
        userListVo.setGarageId(garage.getId());
        userListVo.setWorkstationsNumber(garage.getWorkstationsNumber());
        if (garage.getShopPhotos() != null) {
            userListVo.setGaragePhotoList(garage.getShopPhotos().split(","));

        }
        userListVo.setUserType(BusinessConstants.dict.user_type_3);
        userListVo.setDistance(garage.getDistance());
//        userListVo.setLevel(garage.getLevel());
        userListVo.setScore(garage.getAvgScore());
        if (garage.getServiceTypeIds() != null) {
            userListVo.setServiceTypeIdArray(garage.getServiceTypeIds().split(","));
        }
        userListVo.setOrderTime(garage.getAppointmentTime());
        userListVo.setLongitude(garage.getLongitude());
        userListVo.setLatitude(garage.getLatitude());
        userListVo.setAddress(garage.getAddressName());
        userListVo.setDesc(garage.getIntroduction());
//        userListVo.setWorkYears(garage.getWorkYears());
        userListVo.setServiceCount(garage.getCompleteOrderCount());
        userListVo.setLevel(new BigDecimal(garage.getLevel()) );
        return userListVo;
    }

    private UserListVo mapTechnicianToUserListVo(Technician technician) {
        UserListVo userListVo = new UserListVo();
        userListVo.setUserId(technician.getUserId());
        userListVo.setName(technician.getName());
        userListVo.setAvatar(technician.getAvatar());
        userListVo.setPhone(technician.getPhone());
        userListVo.setTechnicianId(technician.getId());
//        userListVo.getGaragePhotoList(
        userListVo.setUserType(BusinessConstants.dict.user_type_2);
        userListVo.setDistance(technician.getDistance());
        userListVo.setLevel(technician.getLevel());
        userListVo.setScore(technician.getAvgScore());
        if (technician.getServiceTypeIds() != null) {
            userListVo.setServiceTypeIdArray(technician.getServiceTypeIds().split(","));
        }
        userListVo.setOrderTime(technician.getAppointmentTime());
        userListVo.setLongitude(technician.getLongitude());
        userListVo.setLatitude(technician.getLatitude());
        userListVo.setAddress(technician.getAddressName());
        userListVo.setDesc(technician.getIntroduction());
        userListVo.setWorkYears(technician.getWorkYears());
        userListVo.setServiceCount(technician.getCompleteOrderCount());
        return userListVo;
    }


    /**
     * 验证身份证有效期
     */
    private boolean verifyIdCardPeriod(String realName, String idCardNo, String validityStartDate, String validityEndDate) {
        try {
            // 创建Client
            com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                    .setAccessKeyId(aliyunConfig.getAccessKeyId())
                    .setAccessKeySecret(aliyunConfig.getAccessKeySecret());
            config.endpoint = "cloudauth.aliyuncs.com";

            com.aliyun.cloudauth20190307.Client client = new com.aliyun.cloudauth20190307.Client(config);

            // 创建请求对象
            Id2MetaPeriodVerifyRequest request = new Id2MetaPeriodVerifyRequest()
                    .setParamType("normal")  // 使用明文方式
                    .setUserName(realName)
                    .setIdentifyNum(idCardNo)
                    .setValidityStartDate(validityStartDate)
                    .setValidityEndDate(validityEndDate);

            // 创建运行时选项
            com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();

            // 发送请求
            Id2MetaPeriodVerifyResponse response = client.id2MetaPeriodVerifyWithOptions(request, runtime);

            // 判断结果
            if (response != null && response.getBody() != null) {
                String code = response.getBody().getCode();
                if ("200".equals(code)) {
                    // 1: 校验一致; 2: 校验不一致; 3: 查无记录
                    return "1".equals(response.getBody().getResultObject().getBizCode());
                }

                log.error("身份证有效期核验失败 - code: {}, message: {}",
                        code, response.getBody().getMessage());
            } else {
                log.error("身份证有效期核验失败 - 响应为空");
            }
            return false;

        } catch (Exception e) {
            log.error("身份证有效期核验异常", e);
            return false;
        }
    }

    @Override
    public Integer updateUser(SysUser user) {

        return userMapper.updateUser(user);
    }

    @Override
    public List<UserListVo> listByServiceType(TechnicianSearchReqBo technician) {
        return null;
    }

    @Override
    public SysUser getUserById(Long userId) {
        return userMapper.selectUserById(userId);
    }

    @Override
    public List<SysUser> selectUserList(SysUser user) {
        return userMapper.selectUserListByuser(user);
    }

    @Override
    public SysUser selectUserByUserId(Long userId) {
        return userMapper.selectUserById(userId);
    }

}
